package com.cyy.user.textbluetoothble;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.cyy.user.textbluetoothble.Adapter.DeviceAdapter;
import com.litesuits.bluetooth.LiteBluetooth;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    private TextView tv_state,tv_data;
    private final static String TAG = "MainActivity";
    private BluetoothAdapter mBlueToothAdapter;
    private Button button;
    private List<BluetoothDevice> mListBluetoothDevice = new ArrayList<>();
    private DeviceAdapter adapter;
    private ListView mListView;
    private BluetoothGatt mBluetoothGatt;
    private BluetoothDevice bluetoothDevice;
    private BluetoothGattCharacteristic mDataCharacteristic;
    private BluetoothGattCharacteristic mWriteCharateristic;
    private BluetoothGattCharacteristic mNotifyCharceristic;
    private List<String> list = new ArrayList<>();
    private LiteBluetooth liteBluetooth;
    private final static long SCAN_PERIOD = 10000;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.btn_scan);
        mListView = (ListView) findViewById(R.id.ListView_device);
        tv_state = (TextView) findViewById(R.id.tv_state);
        tv_data = (TextView) findViewById(R.id.tv_data);
        //获取蓝牙管理
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        //获取适配器
        mBlueToothAdapter = bluetoothManager.getAdapter();
        //动态的添加权限.6.0以后
        isPermission();

        adapter = new DeviceAdapter(this,mListBluetoothDevice);
        mListView.setAdapter(adapter);
        //ListView的点击事件。
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                //停止搜索
                mBlueToothAdapter.stopLeScan(mScanCallback);
                //获取到某一个蓝牙设备。
                bluetoothDevice = mListBluetoothDevice.get(i);
                //对ble的操作其实也是对bluetoothGatt的操作。
                mBluetoothGatt = bluetoothDevice.connectGatt(MainActivity.this,false,bluetoothGattCallback);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mListBluetoothDevice.clear();
                        adapter.notifyDataSetChanged();
                    }
                });

            }
        });
        /**
         * 接受数据的TextView
         */
       // tv_data.setText(TAG);
    }
    /**
     * 动态的添加权限的方法。
     */
    private void isPermission() {
        if (Build.VERSION.SDK_INT >= 23) {
            //判断是否有权限
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    || ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
                    ) {
                //请求权限
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.CAMERA},
                        0);
                //判断是否需要 向用户解释，为什么要申请该权限
                if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                        Manifest.permission.READ_CONTACTS)) {
                    Toast.makeText(this, "shouldShowRequestPermissionRationale", Toast.LENGTH_SHORT).show();
                }
            }

        }
    }
    /**
     * 点击搜索蓝牙设备.通过回掉的方式添加设备.
     */
    public void scanAction(View view){
        //首先清空集合中存在的设备.
        mListBluetoothDevice.clear();
        //开始搜索设备.
        mBlueToothAdapter.startLeScan(mScanCallback);
   //     scanDevicesPeriod();
    }

    /**
     * 点击发送命令
     */
    public void writeAction(View view){
        //写入数据
        byte[] dataByte1 = {(byte)0xAA, 0x01, 0x06, 0x00,0x00,0x00,0x00,0x03, 0x00,(byte) 0xB4};
        mWriteCharateristic.setValue(dataByte1);
        boolean state = mBluetoothGatt.writeCharacteristic(mWriteCharateristic);
        //跳转
        Log.i(TAG,"有没有写入数据------------>"+state);
        Intent intent = new Intent(MainActivity.this,NotifyActivity.class);
        intent.putStringArrayListExtra("array", (ArrayList<String>) list);
        startActivity(intent);

    }


    //回掉系统
    private BluetoothAdapter.LeScanCallback mScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice bluetoothDevice, int i, byte[] bytes) {
            Log.i(TAG,"name----->"+bluetoothDevice.getName() +"mac----->"+bluetoothDevice.getAddress());
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    /**
                     * 三个参数分别是(1)设备，（2）信号强度 （3）
                     */
                    if(!mListBluetoothDevice.contains(bluetoothDevice)){
                        mListBluetoothDevice.add(bluetoothDevice);
                        adapter.notifyDataSetChanged();
                    }
                }
            });
        }
    };

    /**
     * bluetoothGattCallback的接口回掉的方法。
     */
    private BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
        /**
         * 判断设备是否连接的方法
         */
        @Override
        public void onConnectionStateChange(final BluetoothGatt gatt, int status, final int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            /**
             * 不同的链接的状态
             */
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    switch (newState){
                        case BluetoothGatt.STATE_CONNECTED:
                            /**
                             * 寻找服务，如果这个方法没有实现，打印不出services和characteristics.
                             */
                            gatt.discoverServices();
                            tv_state.setText("已连接");
                        break;
                        case BluetoothGatt.STATE_CONNECTING:
                            tv_state.setText("连接中");
                            break;
                        case BluetoothGatt.STATE_DISCONNECTED:
                            tv_state.setText("已断开");
                            break;
                        case BluetoothGatt.STATE_DISCONNECTING:
                            tv_state.setText("断开中");
                            break;
                        default:
                            break;
                    }
                }
            });
        }
        /**
         * 设备被发现的回掉方法。可以发现所有的设备的services和characteristic。
         */
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            if(status==BluetoothGatt.GATT_SUCCESS){
                List<BluetoothGattService> bluetoothGattServers = mBluetoothGatt.getServices();
                //遍历集合
                for(BluetoothGattService ListBluetoothServer: bluetoothGattServers){
                    Log.i(TAG,"server---------> : "+ListBluetoothServer.getUuid().toString());

                    List<BluetoothGattCharacteristic> bluetoothGattCharacteristics =
                            ListBluetoothServer.getCharacteristics();
                    for(BluetoothGattCharacteristic ListBluetoothGattCharacteristic: bluetoothGattCharacteristics){
                        Log.i(TAG,"characteristic---> :"+ListBluetoothGattCharacteristic.getUuid().toString());

                        if(ListBluetoothGattCharacteristic.getUuid().toString().equals("0000ffe1-0000-1000-8000-00805f9b34fb")){
                            mWriteCharateristic =ListBluetoothGattCharacteristic;
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Log.i(TAG,"notify有没有到达----------->"+mWriteCharateristic);
                                }
                            });
                        }
                        if(ListBluetoothGattCharacteristic.getUuid().toString().equals("0000ffe0-0000-1000-8000-00805f9b34fb")){
                            mNotifyCharceristic = ListBluetoothGattCharacteristic;
                            enableNotification(true,mNotifyCharceristic);
                        }

                        if(ListBluetoothGattCharacteristic.getUuid().toString().equals("0000ffe2-0000-1000-8000-00805f9b34fb")){
                            mDataCharacteristic = ListBluetoothGattCharacteristic;
                            enableNotification(true,mDataCharacteristic);
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Log.i(TAG,"notify有没有到达----------->"+mDataCharacteristic);
                                }
                            });
                        }
                    }
                }
            }
        }
        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            }
        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);
        }
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            /**
             * 验证的是我写入数据返回给我的值。
             */
            if(characteristic.getUuid().toString().equals(mDataCharacteristic.getUuid().toString())){
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "我测试一下-------------->", Toast.LENGTH_SHORT).show();
                        Log.i(TAG,"---------------------------->");
                    }
                });
                final byte[] value = characteristic.getValue();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Log.i(TAG,"E134 notify的内容"+Bytes2HexString(value));
                        list.add(Bytes2HexString(value));

                    }
                });
            }
            /**
             * 当我点烟的时候系统给我的
             */
            if(characteristic.getUuid().toString().equals(mNotifyCharceristic.getUuid().toString())){

                final byte[] value = characteristic.getValue();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Log.i(TAG,"E134 notify的内容"+Bytes2HexString(value));
                        tv_data.setText(Bytes2HexString(value));
                    }
                });
            }
        }

        @Override
        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorRead(gatt, descriptor, status);


        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(gatt, descriptor, status);
        }

        @Override
        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
            super.onReliableWriteCompleted(gatt, status);
        }

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            super.onReadRemoteRssi(gatt, rssi, status);
        }

        @Override
        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
            super.onMtuChanged(gatt, mtu, status);
        }
    };

    private boolean enableNotification(boolean enable,BluetoothGattCharacteristic characteristic) {
        if(mBluetoothGatt==null || characteristic==null){
            return false;
        }
        if(!mBluetoothGatt.setCharacteristicNotification(characteristic,enable)){
            return false;
        }
        BluetoothGattDescriptor clientconfig = characteristic.getDescriptor
                (UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
        if(clientconfig==null){
            return false;
        }
        if(enable){
            clientconfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        }else {
            clientconfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
        }
        return mBluetoothGatt.writeDescriptor(clientconfig);
    }

    private final byte[] hex = "0123456789ABCDEF".getBytes();

    // 从字节数组到十六进制字符串转�?
    private String Bytes2HexString(byte[] b) {

        byte[] buff = new byte[2 * b.length];
        for (int i = 0; i < b.length; i++) {
            buff[2 * i] = hex[(b[i] >> 4) & 0x0f];
            buff[2 * i + 1] = hex[b[i] & 0x0f];
        }
        return new String(buff);
    }

}
